package com.wanxi.chat.server;



import com.wanxi.chat.codec.Invocation;
import com.wanxi.chat.model.ChatEntity;
import com.wanxi.chat.mongo.api.MongoFeignClient;
import com.wanxi.chat.offline.api.OfflineFeignClient;
import com.wanxi.chat.vo.ChatQueryVO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelId;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * 客户端 Channel 管理器。提供两种功能：
 * 1. 客户端 Channel 的管理
 * 2. 向客户端 Channel 发送消息
 */
@Component
public class NettyChannelManager {

//    @Autowired
//    private OffLineService offLineService;
    private static final AttributeKey<String> CHANNEL_ATTR_KEY_USER = AttributeKey.newInstance("user");

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OfflineFeignClient offlineFeignClient;
    @Autowired
    private MongoFeignClient mongoFeignClient;
    /**
     * Channel 映射
     */
    private ConcurrentMap<ChannelId, Channel> channels = new ConcurrentHashMap<>();
    /**
     * 用户与 Channel 的映射。
     */
    private ConcurrentMap<String, Channel> userChannels = new ConcurrentHashMap<>();

  //  private ChatRepositoryController chatRepositoryController = new ChatRepositoryController();
    /**
     * 添加 Channel 到 {@link #channels} 中
     */
    public void add(Channel channel) {
        channels.put(channel.id(), channel);
        logger.info("[add][一个连接({})加入]", channel.id());
    }

    /**
     * @param channel Channel
     * @param userId 用户id
     */
    public void addUser(Channel channel, String userId) {
        Channel existChannel = channels.get(channel.id());
        if (existChannel == null) {
            logger.error("[addUser][连接({}) 不存在]", channel.id());
            return;
        }
        // 设置属性
        channel.attr(CHANNEL_ATTR_KEY_USER).set(userId);
        // 添加到 userChannels
        userChannels.put(userId, channel);
    }

    /**
     * @param channel Channel
     */
    public void remove(Channel channel) {
        // 移除 channels
        channels.remove(channel.id());
        // 移除 userChannels
        if (channel.hasAttr(CHANNEL_ATTR_KEY_USER)) {
            userChannels.remove(channel.attr(CHANNEL_ATTR_KEY_USER).get());
        }
        logger.info("[remove][一个连接({})离开]", channel.id());
    }

    /**
     * 向指定用户发送消息
     * @param toId 接收方用户id
     * @param invocation 消息体
     */
    public void send(String toId, Invocation invocation) {
        //此处存聊天消息
        ChatQueryVO chatQueryVO = new ChatQueryVO();
        chatQueryVO.setToId(toId);
        chatQueryVO.setContent(invocation.getMessage());
        mongoFeignClient.mongoAddFeign(chatQueryVO);
//        chatRepository.add(chatQueryVO);
//        // 获得用户对应的 Channel
        Channel channel = userChannels.get(toId);
        if (channel == null) {
            //此处存离线消息
            ChatEntity chatEntity=new ChatEntity();
            chatEntity.setId(toId);
            chatEntity.setContent(invocation.getMessage());
            offlineFeignClient.redisSaveFeign(chatEntity);
//            offLineService.Save(chatEntity);
            logger.error("[send][连接不存在]");
            return;
        }
        if (!channel.isActive()) {
            logger.error("[send][连接({})未激活]", channel.id());
            return;
        }
        // 发送消息
        channel.writeAndFlush(invocation);
    }


}
